package com.jadows.tdog.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.jadows.tdog.base.PageRecords;
import com.jadows.tdog.domain.ChatMessage;
import com.jadows.tdog.domain.Contact;
import com.jadows.tdog.po.ChatMessagePagePo;
import com.jadows.tdog.repository.ChatMessageRepository;
import com.jadows.tdog.repository.ContactRepository;
import com.jadows.tdog.service.ChatMessageService;
import com.jadows.tdog.state.OnlineUserRegister;
import com.jadows.tdog.util.SecurityUtil;
import com.jadows.tdog.util.UnionUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author taojiacheng
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class ChatMessageServiceImpl implements ChatMessageService {

    final ChatMessageRepository chatMessageRepository;
    final ContactRepository contactRepository;
    final MongoTemplate mongoTemplate;
    final OnlineUserRegister onlineUserRegister;
    final RedissonClient redissonClient;


    @Override
    public PageRecords<ChatMessage> pageChatMessage(ChatMessagePagePo chatMessagePagePo) {
        // 参数校验
        checkParams(chatMessagePagePo);
        // 检索私聊消息记录
        String currentMemberId = SecurityUtil.getCurrentUser().getMemberId();
        String unionId = UnionUtil.getUnionId(currentMemberId, chatMessagePagePo.getTargetUid());
        Contact contact = contactRepository.findContactByUnionId(unionId);
        if (contact == null) {
            log.warn("当前用户:{} 与 {} 不存在联系人关系", currentMemberId, chatMessagePagePo.getTargetUid());
            return new PageRecords<>(chatMessagePagePo.getLastMessageId(), Collections.emptyList());
        }
        // 当前用户联系人信息
        Contact.ContactInfo contactInfo = contact.getContactInfoByUid(currentMemberId);
        if (contactInfo == null) {
            log.warn("当前用户:{} 与 {} 不存在联系人关系", currentMemberId, chatMessagePagePo.getTargetUid());
            return new PageRecords<>(chatMessagePagePo.getLastMessageId(), Collections.emptyList());
        }

        Query query = new Query().with(Sort.by(Sort.Direction.DESC, "messageId"));
        query.addCriteria(Criteria.where("action").is(chatMessagePagePo.getAction()));
        query.addCriteria(Criteria.where("unionId").is(unionId));
        // 聊天内容检索
        if (StrUtil.isNotBlank(chatMessagePagePo.getContent())) {
            query.addCriteria(Criteria.where("content").regex(chatMessagePagePo.getContent(), "i"));
        }
        Long lastMessageId = chatMessagePagePo.getLastMessageId();
        Integer pageSize = chatMessagePagePo.getPageSize();
        // 查询id 小于 lastMessageId 的 pageSize 条消息
        Criteria messageIdCriteria = Criteria.where("messageId").lt(lastMessageId);
        Long lastMessageIdBeforeDeleted = contactInfo.getLastMessageIdBeforeDeleted();
        // 所查询的消息不能超过联系人删除时的最后一条消息
        if (lastMessageIdBeforeDeleted != null) {
            messageIdCriteria.gt(lastMessageIdBeforeDeleted);
        }
        query.addCriteria(messageIdCriteria);
        query.limit(pageSize);
        List<ChatMessage> messages = mongoTemplate.find(query, ChatMessage.class);
        return new PageRecords<>(lastMessageId, messages);
    }


    @Override
    public Map<String, ChatMessageRepository.ChatMessageGroup> findLast10Messages(List<String> unionIds) {
        if (CollUtil.isEmpty(unionIds)) {
            return Collections.emptyMap();
        }
        List<ChatMessageRepository.ChatMessageGroup>
                last10ChatMessageGroup = chatMessageRepository.findLast10MessageByUnionIdIn(mongoTemplate, unionIds);
        for (ChatMessageRepository.ChatMessageGroup chatMessageGroup : last10ChatMessageGroup) {
            List<ChatMessage> messages = chatMessageGroup.getMessages();
            if (CollUtil.isEmpty(messages)) {
                continue;
            }
            // 倒序
            Collections.reverse(messages);
            chatMessageGroup.setMessages(messages);
        }
        // unionId 分组
        return last10ChatMessageGroup.stream()
                .collect(Collectors.toMap(ChatMessageRepository.ChatMessageGroup::getUnionId, Function.identity()));
    }


    /**
     * 参数校验
     *
     * @param chatMessagePagePo 参数
     */
    private void checkParams(ChatMessagePagePo chatMessagePagePo) {
        Integer pageSize = chatMessagePagePo.getPageSize();
        if (pageSize < 0 || pageSize > 100) {
            throw new IllegalArgumentException("pageSize must between 0 and 100");
        }
    }
}
